﻿/**
* Author      :何世孟
* version	  :v3.3.full
* description :修复了Meng.ajax()方法中，data不能为空的bug。
*              重写了Meng.animate()方法。vv10000
* 对方
*/

(function(window){

    var Meng = {}, _Meng = window.Meng, document = window.document;
    
    window.Meng = Meng;
    
    Meng.dom = Meng.Event = Meng.str = Meng.fn = Meng.ui = Meng.ajax = Meng.xml = {};
    
    Meng.noConflict = function(){
        window.Meng = _Meng;
        return _Meng;
    };
    /**
	* 获取ID的节点对象
	* @params elem {string}
	* @returns DOMObject
	*/
    Meng.getId = Meng.dom.getId = function(elem){
        return document.getElementById(elem);
    };
    /**
	* 获取标签元素对象
	* @params name {string} 标签名
	* @params elem {DOMObject} 查找name的开始范围,默认为document
	* @returns TagDomObject
	*/
    Meng.getTag = Meng.dom.getTag = function(name, elem){
        return (elem || document).getElementsByTagName(name);
    };
    
    Meng.getClass = Meng.dom.getClass = function(className, context){
        context = context || document;
        if (context.getElementsByClassName) {
            return context.getElementsByClassName(className);
        }
        var nodes = context.getElementsByTagName('*'), ret = [];
        for (var i = 0; i < nodes.length; i++) {
            if (Meng.hasClass(nodes[i], className)) 
                ret.push(nodes[i]);
        }
        return ret;
    };
    
    Meng.children = Meng.dom.children = function(elem){
        for (var children = [], child = elem.firstChild; child; child = child.nextSibling) {
            if (child.nodeType == 1) {
                children.push(child);
            }
        }
        return children;
    };
    
    Meng.addClass = Meng.dom.addClass = function(elem, className){
        var classArray = ('string' == typeof className) ? [className] : className, result = elem.className, classMatch = " " + result + " ", i = 0, l = classArray.length;
        
        for (; i < l; i++) {
            if (classMatch.indexOf(" " + classArray[i] + " ") < 0) {
                result += (result ? ' ' : '') + classArray[i];
            }
        }
        
        elem.className = result;
        return elem;
    };
    
    Meng.delClass = Meng.dom.delClass = function(elem, className){
        var names = elem.className.split(/\s+/);
        for (var i = 0; i < names.length; i++) {
            if (names[i] == className) 
                delete names[i];
        }
        elem.className = names.join(" ");
        return elem;
    };
    
    Meng.hasClass = Meng.dom.hasClass = function(node, className){
        var names = node.className;
        for (var i = 0; i < names.length; i++) {
            if (names[i] == className) 
                return true;
        }
        return false;
    };
    
    Meng.getStyle = Meng.dom.getStyle = function(elem, name){
        if (window.getComputedStyle) {
            var style = window.getComputedStyle(elem, null);
            return style.getPropertyValue(name);
        }
        else {
            var style = elem.style, curStyle = elem.currentStyle;
            //透明度 from youa
            if (name == "opacity") {
                if (/alpha\(opacity=(.*)\)/i.test(curStyle.filter)) {
                    var opacity = parseFloat(RegExp.$1);
                    return opacity ? opacity / 100 : 0;
                }
                return 1;
            }
            if (name == "float") {
                name = "styleFloat";
            }
            var ret = curStyle[name] || curStyle[Meng.str.camelize(name)];
            //单位转换 from jqury
            if (!/^-?\d+(?:px)?$/i.test(ret) && /^\-?\d/.test(ret)) {
                var left = style.left, rtStyle = elem.runtimeStyle, rsLeft = rtStyle.left;
                
                rtStyle.left = curStyle.left;
                style.left = ret || 0;
                ret = style.pixelLeft + "px";
                
                style.left = left;
                rtStyle.left = rsLeft;
            }
            return ret;
        }
    };
    
    Meng.setStyle = Meng.dom.setStyle = function(elems, style, value){
        elems = !elems.length ? [elems] : elems;
        if (typeof style == "string") {
            var s = style;
            style = {};
            style[s] = value;
        }
        Meng.fn.each(elems, function(){
            var elem = this;
            Meng.fn.each(style, function(name){
                var value = style[name], ie = Meng.browser.ie;
                if (name == 'opacity' && ie) {
                    //ie透明度设置 from jquery
                    elem.style.filter = (elem.currentStyle && elem.currentStyle.filter || "").replace(/alpha\([^)]*\)/, "") + " alpha(opacity=" + (value * 100 | 0) + ")";
                }
                else 
                    if (name == 'float') {
                        elem.style[ie ? 'styleFloat' : 'cssFloat'] = value;
                    }
                    else {
                        elem.style[Meng.camelize(name)] = value;
                    }
            });
        });
    };
    
    Meng.create = Meng.dom.create = function(elem){
        return document.createElementNS ? document.createElementNS('http://www.w3.org/1999/xhtml', elem) : document.createElement(elem);
    };
    
    Meng.remove = Meng.dom.remove = function(elem){
        elem && elem.parentNode.removeChild(elem);
    };
    
    Meng.empty = Meng.dom.empty = function(elem){
        while (elem.firstChild) 
            Meng.dom.remove(elem.firstChild);
    };
    
    Meng.append = Meng.dom.append = function(parent, elem){
        parent.appendChild(Meng.dom.checkElem(elem));
    };
    
    Meng.before = Meng.dom.before = function(parent, before, elem){
        if (elem == null) {
            elem = before;
            before = parent;
            parent = before.parentNode;
        }
        parent.insertBefore(Meng.dom.checkElem(elem), before);
    };
    
    Meng.checkElem = Meng.dom.checkElem = function(elem){
        return elem && elem.constructor == String ? document.createTextNode(elem) : elem;
    };
    Meng.attr = Meng.dom.attr = function(elem, name, value){
        if (!name || name.constructor != String) 
            return '';
        name = {
            'for': 'htmlFor',
            'class': 'className'
        }[name] ||
        name;
        if (value != null) {
            elem[name] = value;
            if (elem.setAttribute) 
                elem.setAttribute(name, value);
        }
        return elem[name] || elem.getAttribute(name) || '';
    };
    /**
     * 在目标元素的指定位置插入HTML代码
     * @param {HTMLElement|string} element 目标元素或目标元素的id
     * @param {string} position 插入html的位置信息，取值为beforeBegin,afterBegin,beforeEnd,afterEnd
     * @param {string} html 要插入的html
     * @remark
     *
     * 对于position参数，大小写不敏感<br>
     * 参数的意思：beforeBegin&lt;span&gt;afterBegin   this is span! beforeEnd&lt;/span&gt; afterEnd <br />
     * 此外，如果使用本函数插入带有script标签的HTML字符串，script标签对应的脚本将不会被执行。
     *
     * @returns {HTMLElement} 目标元素
     */
    Meng.insertHTML = Meng.dom.insertHTML = function(element, position, html){
    
        var range, begin;
        
        //在opera中insertAdjacentHTML方法实现不标准，如果DOMNodeInserted方法被监听则无法一次插入多element
        //by lixiaopeng @ 2011-8-19
        if (element.insertAdjacentHTML && !Meng.browser.opera) {
            element.insertAdjacentHTML(position, html);
        }
        else {
            // 这里不做"undefined" != typeof(HTMLElement) && !window.opera判断，其它浏览器将出错？！
            // 但是其实做了判断，其它浏览器下等于这个函数就不能执行了
            range = element.ownerDocument.createRange();
            // FF下range的位置设置错误可能导致创建出来的fragment在插入dom树之后html结构乱掉
            // 改用range.insertNode来插入html, by wenyuxiang @ 2010-12-14.
            position = position.toUpperCase();
            if (position == 'AFTERBEGIN' || position == 'BEFOREEND') {
                range.selectNodeContents(element);
                range.collapse(position == 'AFTERBEGIN');
            }
            else {
                begin = position == 'BEFOREBEGIN';
                range[begin ? 'setStartBefore' : 'setEndAfter'](element);
                range.collapse(begin);
            }
            range.insertNode(range.createContextualFragment(html));
        }
        return element;
    };
    
    /** 
     * 获取元素相对于浏览器窗口的坐标
	 * return {top,right,bottom,left}
     */
    Meng.getElemViewPosition = Meng.dom.getElemViewPosition = function getElementViewPostion(elem){
        if (document.documentElement.getBoundingClientRect) {
            var elemBCR = elem.getBoundingClientRect();
            return {
                top: elemBCR.top,
                right: elemBCR.right,
                bottom: elemBCR.bottom,
                left: elemBCR.left
            }
        }
    };
    /**
     * 获取滚动条的位置
	 * return {top,left}
     */
    Meng.getScrollPosition = Meng.dom.getScrollPosition = function getScollPos(){
        return {
            top: document.documentElement.scrollTop || document.body.scrollTop,
            left: document.documentElement.scrollLeft || document.body.scrollLeft
        }
    };
    /** 
     * 获取元素在浏览器中的坐标
	 * @elem {HTMLDOMElement}
	 * return {left,height}
     */
    Meng.getElemPosition = Meng.dom.getElemPosition = function(elem){
        return {
            top: Meng.dom.getElemViewPosition(elem).top + Meng.dom.getScrollPosition().top,
            left: Meng.dom.getElemViewPosition(elem).left + Meng.dom.getScrollPosition().left
        };
    };
    /**
     * 获取页面尺寸
	 * return {width,height} 
     */
    Meng.getPageSize = Meng.dom.getPageSize = function(){
        var scrW, scrH, w = window, d = document;
        if (w.innerHeight && w.scrollMaxY) {
            // Mozilla
            scrW = w.innerWidth + w.scrollMaxX;
            scrH = w.innerHeight + w.scrollMaxY;
        }
        else 
            if (d.body.scrollHeight > d.body.offsetHeight) {
                // all but IE Mac
                scrW = d.body.scrollWidth;
                scrH = d.body.scrollHeight;
            }
            else 
                if (d.body) { // IE Mac
                    scrW = d.body.offsetWidth;
                    scrH = d.body.offsetHeight;
                }
        
        var browserView = Meng.dom.getBrowserView(), winW = browserView.width, winH = browserView.height,        // for small pages with total size less then the viewport
        pageW = (scrW < winW) ? winW : scrW, pageH = (scrH < winH) ? winH : scrH;
        return {
            width: pageW,
            height: pageH
        };
    };
    /** 
     * 获取浏览器窗口大小
	 * return {width,height}
     */
    Meng.getBrowserView = Meng.dom.getBrowserView = function(){
        var winW, winH, w = window, d = document;
        if (w.innerHeight) { // all except IE
            winW = w.innerWidth;
            winH = w.innerHeight;
        }
        else 
            if (d.documentElement && d.documentElement.clientHeight) {
                // IE 6 Strict Mode
                winW = d.documentElement.clientWidth;
                winH = d.documentElement.clientHeight;
            }
            else 
                if (d.body) { // other
                    winW = d.body.clientWidth;
                    winH = d.body.clientHeight;
                }
        return {
            width: winW,
            height: winH
        };
    };
	/**
	* 注册监听函数
	* @element {HTMLDOMElement} 
	* @type {string} 监听方式，如：click,mousedown,mouseover,mouseup,focus,keypress等
	* @handler {Function} 给element所注册的函数
	* @return void
	*/
    Meng.addEvent = Meng.Event.addEvent = function(element, type, handler){
        if (element.addEventListener) {
            element.addEventListener(type, handler, false);
        }
        else {
            if (!handler.$$guid) 
                handler.$$guid = Meng.guid++;
            if (!element.events) 
                element.events = {};
            var handlers = element.events[type];
            if (!handlers) {
                handlers = element.events[type] = {};
                if (element["on" + type]) {
                    handlers[0] = element["on" + type];
                }
            }
            handlers[handler.$$guid] = handler;
            element["on" + type] = Meng.handleEvent;
        }
    };
    
    Meng.Event.guid = 1;
    
    Meng.removeEvent = Meng.Event.removeEvent = function(element, type, handler){
        if (element.removeEventListener) {
            element.removeEventListener(type, handler, false);
        }
        else {
            if (element.events && element.events[type]) {
                delete element.events[type][handler.$$guid];
            }
        }
    };
    
    Meng.handleEvent = Meng.Event.handEvent = function(event){
        var returnValue = true;
        event = event || Meng.fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event);
        var handlers = this.events[event.type];
        for (var i in handlers) {
            this.$$handleEvent = handlers[i];
            if (this.$$handleEvent(event) === false) {
                returnValue = false;
            }
        }
        return returnValue;
    };
    Meng.fixEvent = Meng.Event.fixEvent = function(event){
        event.preventDefault = Meng.fixEvent.preventDefault;
        event.stopPropagation = Meng.fixEvent.stopPropagation;
        return event;
    };
    Meng.fixEvent.preventDefault = function(){
        this.returnValue = false;
    };
    Meng.fixEvent.stopPropagation = function(){
        this.cancelBubble = true;
    };
    
    Meng.camelize = Meng.str.camelize = function(s){
        return s.replace(/-([a-z])/ig, function(all, letter){
            return letter.toUpperCase();
        });
    };
    /**
     * 可以遍历数组、json对象、Dom对象集
     */
    Meng.each = Meng.fn.each = function(obj, fn, args){
        if (args) {
            if (obj.length == undefined) {
                for (var i in obj) 
                    fn.apply(obj, args);
            }
            else {
                for (var i = 0, ol = obj.length; i < ol; i++) {
                    if (fn.apply(obj, args) === false) 
                        break;
                }
            }
        }
        else {
            if (obj.length == undefined) {
                for (var i in obj) 
                    fn.call(obj, i, obj);
            }
            else {
                for (var i = 0, ol = obj.length, val = obj[0]; i < ol && fn.call(val, i, val) !== false; val = obj[++i]) {
                }
            }
        }
        return obj;
    };
    /**
	* 获取浏览器版面，如：
	* Meng.browser.ie = true/false 判断是否是IE浏览器,
	* Meng.browser.ie6~8 = true/false,
	* Meng.browser.firefox = true/false,
	* Meng.browser.chrome = true/false
	*/
    Meng.browser = (function(ua){
        var b = {
            msie: /msie/.test(ua) && !/opera/.test(ua),
            opera: /opera/.test(ua),
            safari: /webkit/.test(ua) && !/chrome/.test(ua),
            firefox: /firefox/.test(ua),
            chrome: /chrome/.test(ua)
        };
        var vMark = "";
        for (var i in b) {
            if (b[i]) {
                vMark = "safari" == i ? "version" : i;
                break;
            }
        }
        b.version = vMark && RegExp("(?:" + vMark + ")[\\/: ]([\\d.]+)").test(ua) ? RegExp.$1 : "0";
        
        b.ie = b.msie;
        b.ie6 = b.msie && parseInt(b.version, 10) == 6;
        b.ie7 = b.msie && parseInt(b.version, 10) == 7;
        b.ie8 = b.msie && parseInt(b.version, 10) == 8;
        
        return b;
    })(window.navigator.userAgent.toLowerCase());
    
    
    /**
	* 动画函数 , 此动画函数只支持opcity,和其它单位px的属性动画。
	* @elem {HTMLElementObject} dom对象
	* @start {JSON} elem的动画变量初始值,如{left:10,top:10,opacity:0}
	* @alter {JSON} elem的动画变量结束与开始的差值,如{left:90,top:90,opacity:100}
	* @duration {Number} elem的动画时间
	* @callBack {Function} 动画结束是的回调函数
	* @tween {Function} 动画的运动算子，默认是加速后减速的算子。
	* return function(){}
	*/
    Meng.animate = Meng.ui.animate = function (elem, start, alter, duration, callBack, tween) {
			var curTime = 0 , timeout = null;
			tween = tween || Meng.Tween;
			callBack = callBack || function(){};
			duration = duration-(duration%10);//duration需被10整除,可以清除动画结束时的误差。
			function change() {
				if (curTime < duration) {
					curTime += 10;
					Meng.each(start, function (key) {
						var value = tween(curTime, start[key], alter[key], duration);
						if (key == 'opacity') {
							Meng.setStyle(elem, 'opacity', value);
						} else {
							Meng.setStyle(elem, key, value + 'px');
						}
					});
					timeout = setTimeout(change, 10);
				}else{
					callBack();
				}
			};
			change();
			return function () {
				clearTimeout(timeout);
			};
		};
    
    Meng.Tween = Meng.ui.Tween = function(t,b,c,d){
			if ((t/=d/2) < 1) return c/2*t*t + b;
			return -c/2 * ((--t)*(t-2) - 1) + b;
    };
    
    function ajax(options){
        this.url = options.url;
        this.method = options.method || 'get';
        this.responseType = options.responseType || 'text';
        this.success = options.success ||
        function(){
        };
        this.waiting = options.waiting ||
        function(){
        };
        this.stopWaiting = options.stopWaiting ||
        function(){
        };
        this.cache = options.cache || false;
        this.data = this.params(options.data);
        this.XHR = this.createXHR();
        this.init();
    };
    ajax.prototype = {
        init: function(){
            if (/get/i.test(this.method)) {
                this.url += "?" + this.data;
            }
            if (!this.cache) {
                if (this.url.indexOf("?") < 0) 
                    this.url += "?";
                this.url += "&" + (+new Date());
            }
            this.XHR.open(this.method, this.url, true);
            var _this = this;//为了兼容IE6
            this.XHR.onreadystatechange = function(){
                if (_this.XHR.readyState === 4 && _this.XHR.status === 200) {
                    _this.stopWaiting();
                    if (/xml/i.test(_this.responseType)) {
                        _this.success(_this.XHR.responseXML);
                    }
                    else 
                        if (/json/i.test(_this.responseType))/* || /text/i.test(_this.responseType))*/ {
                            _this.success(eval('(' + _this.XHR.responseText + ')'));
                        }
                        else {
                            _this.success(_this.XHR.responseText);
                        }
                }
                else {
                    _this.waiting();
                }
            };
            if (/post/i.test(this.method)) {
                this.XHR.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
                this.XHR.send(this.data);
            }
            else {
                this.XHR.send();
            }
        },
        createXHR: function(){
            return window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"); //IE6
        },
        params: function(o){
			if(!o) return '';
            var a = [];
            Meng.each(o, function(k){
                a.push(k + '=' + encodeURIComponent(this[k]));
            });
            return a.join("&");
        }
    };
    Meng.ajax = function(options){
        return new ajax(options);
    };
    Meng.getJson = function(options){
        options.responseType = 'json';
        return new ajax(options);
    };
    
    Meng.selectSingleNode = Meng.xml.selectSingleNode = function(xmlDoc, xpath){
        if ("selectSingleNode" in xmlDoc) {
            return xmlDoc.selectSingleNode(xpath);
        }
        else {
            var eva = new XPathEvaluator();
            var result = eva.evaluate(xpath, xmlDom, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
            if (result) { //XPath执行失败会返回null
                var node;
                while (node = result.iterateNext()) {
                    return node;
                }
            }
        }
    };
    
    Meng.selectNodes = Meng.xml.selectNodes = function(xmlDoc, xpath){
        if ("selectNodes" in xmlDoc) {
            return xmlDoc.selectNodes(xpath);
        }
        else {
            var eva = new XPathEvaluator();
            var result = eva.evaluate(xpath, xmlDoc, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
            if (result) { //XPath执行失败会返回null
                var node, nodes = [];
                while (node = result.iterateNext()) {
                    nodes.push(node);
                }
                return nodes;
            }
        }
    };
    
    Meng.getXML = Meng.xml.getXML = function(xmlNode){
        if (xmlNode.xml) 
            return xmlNode.xml;
        else {
            var s = new XMLSerializer();
            return s.serializeToString(xmlNode, "text/xml");
        }
    };
    /**
     * 扩展Meng命名空间函数的函数,如：
	 * Meng.extend({
	 * 		fn1:function(params){},
	 * 		fn2:function(params){}
	 * });
	 * 调用方法：Meng.fn1();Meng.fn2();
     */
    Meng.extend = function(source){
        for (var property in source) {
            var copy = source[property];
            if (Meng === copy) 
                continue;
            if (typeof copy === "object") {
                Meng[property] = arguments.callee(Meng[property] || {}, copy);
            }
            else {
                Meng[property] = copy;
            }
        }
        return Meng;
    };
    /** 
     IE6下的背景图片每次使用都会重新发送请求(not 本地)，
     连一个hover效果时候同样的背景图片仅仅位置不同而已，
     ie6都会再次发送请求。
     */
    if (Meng.browser.ie6) {
        try {
            document.execCommand("BackgroundImageCache", false, true);
        } 
        catch (e) {
        }
    };
    
    })(window, undefined);

